<template>
  <div>
    <div class="title-box">
      <!-- <el-upload
        class="upload-demo"
        :action="uploadUrl"
        :before-upload="beforeUpload"
        :on-error="handleError"
        :file-list="fileList"
        :show-file-list="false"
        :limit="1"
        :http-request="customRequest"
      >
        <el-button type="primary">选择文件</el-button>
      </el-upload> -->

      <el-form :inline="true" label-width="72px" @submit.prevent>
        <el-form-item label="LOTID">
          <el-input
            v-model="lotId"
            placeholder="如 TOLE10065.1"
            @input="lotId = lotId.toUpperCase()"
          />
        </el-form-item>
        <el-form-item label="WFNO">
          <el-input
            v-model="wfNo"
            placeholder="如 1"
            @input="wfNo = wfNo.toUpperCase()"
          />
        </el-form-item>
        <el-form-item label="CP">
          <el-input
            v-model="cpNo"
            placeholder="如 CP1"
            @input="cpNo = cpNo.toUpperCase()"
          />
        </el-form-item>
        <el-form-item label="RP">
          <el-input
            v-model="rpNo"
            placeholder="如 RP0"
            @input="rpNo = rpNo.toUpperCase()"
          />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" :loading="loading" @click="onResolve"
            >解析/获取</el-button
          >
          <el-button @click="loadLast">读取历史</el-button>
        </el-form-item>
      </el-form>

      <el-dialog
        v-model="isDownloading"
        title="解析中..."
        width="400px"
        custom-class="custom-dialog"
      >
        <div class="dialog-content">
          <div class="dialog-text">正在解析stdf文件，请稍候...</div>
          <el-progress
            :percentage="uploadProgress"
            :text-inside="true"
            striped
            :stroke-width="26"
            class="progress-bar"
          />
        </div>
      </el-dialog>
    </div>

    <el-container style="height: 100vh">
      <!-- 左侧测试选择栏 -->
      <el-aside
        width="260px"
        style="border-right: 1px solid #dcdfe6; padding: 10px"
      >
        <div><strong>测试项数据</strong></div>
        <el-input
          v-model="search"
          placeholder="Search..."
          clearable
          size="large"
        />

        <el-scrollbar style="max-height: 80vh; margin-top: 10px">
          <el-tree
            :data="filteredTests"
            node-key="id"
            :default-expand-all="true"
            highlight-current
            @node-click="handleTestClick"
            style="margin-top: 10px"
          >
            <template #default="{ node, data }">
              <span class="tree-node-text" :title="data.label">
                {{ data.label }}
              </span>
            </template>
          </el-tree>
        </el-scrollbar>
      </el-aside>

      <!-- 右侧详细信息 -->
      <el-main style="padding: 0">
        <el-tabs v-model="activeTab" type="border-card">
          <el-tab-pane label="Detailed Info" name="info">
            <div style="padding: 16px">
              <el-card>
                <h4>File Info</h4>
                <p><strong>lotId:</strong> {{ current?.lotId || "N/A" }}</p>
                <p><strong>wfNo:</strong> {{ current?.wfNo || "N/A" }}</p>
                <p><strong>md5:</strong> {{ current?.md5 || "N/A" }}</p>
              </el-card>

              <el-card style="margin-top: 20px">
                <h4>Test Statistics</h4>
                <el-table
                  :data="testStats"
                  v-loading="tabelLoading"
                  style="width: 100%"
                >
                  <el-table-column prop="site" label="site" />
                  <el-table-column prop="unit" label="Unit" />
                  <el-table-column prop="hLimit" label="hLimit" />
                  <el-table-column prop="lLimit" label="lLimit" />
                  <el-table-column prop="failCount" label="failNum" />
                  <el-table-column prop="count" label="count" />
                  <el-table-column prop="cpk" label="Cpk" />
                  <el-table-column prop="stdDev" label="stdDev" />
                  <el-table-column prop="median" label="Median" />
                  <el-table-column prop="mean" label="mean" />
                  <el-table-column prop="max" label="max" />
                  <el-table-column prop="min" label="min" />
                </el-table>
              </el-card>
            </div>
          </el-tab-pane>
          <el-tab-pane label="Trend Chart" name="trend">
            <TrendChart
              v-if="activeTab === 'trend'"
              :active="activeTab === 'trend'"
              :testName="selectedTestName"
              :dbPath="current?.dbPath"
              api-url="http://10.0.8.42:8089/api/Stdf/GetSiteEcharts"
              :jitter="true"
            />
          </el-tab-pane>
          <el-tab-pane label="Histogram" name="histogram">
            <HistogramChart
              v-if="activeTab === 'histogram'"
              apiUrl="http://10.0.8.42:8089/api/Stdf/GetSiteHistogram"
              :active="activeTab == 'histogram'"
              :testName="selectedTestName"
              :dbPath="current?.dbPath"
              mode="bins"
              :stacked="true"
              :showFit="true"
              :showSpecs="true"
              centerOn="mean"
              :enableZoom="true"
            />
          </el-tab-pane>
          <el-tab-pane label="Bin Summary" name="bin" />
          <el-tab-pane label="Wafer Map" name="wafer" />
        </el-tabs>
      </el-main>
    </el-container>
  </div>
</template>

<script setup lang="ts">
import { onMounted, ref, computed, nextTick, watch } from "vue";
import { useDark, useECharts } from "@pureadmin/utils";
import { useStdfStore } from "@/store/stdfStore";
import axios from "axios";
import SparkMD5 from "spark-md5";
import * as signalR from "@microsoft/signalr";
import { ElMessage, ElLoading } from "element-plus";
import TrendChart from "../configuration/components/TrendCharts.vue";
import HistogramChart from "../configuration/components/HistogramCharts.vue";

const uploadStatus = "https://localhost:44389/api/Stdf/status"; // 后端上传接
//const uploadStatus = "http://10.0.8.42:8089/api/Stdf/status"; // 后端上传接口
const fileList = ref([]); // 文件列表
const uploadProgress = ref(0); // 上传进度
const totalChunks = ref(0); // 文件总分块数
const currentChunk = ref(0); // 当前上传的分块
const fileMD5 = ref(""); // 文件的 MD5 校验值
const uploadUrl = "https://localhost:44389/api/Stdf/generate-database"; // 后端上传接口
// const uploadUrl = "http://10.0.8.42:8089/api/Stdf/generate-database"; // 后端上传接口
const chunkedFile = ref([]); // 文件分块数组
const uploadedChunks = ref([]); // 已上传的分块索引

// 查询对应的stdf文件
const lotId = ref("");
const wfNo = ref("");
const cpNo = ref("");
const rpNo = ref("");
const loading = ref(false);

const store = useStdfStore();

const current = computed(() => store.current);
const currentKeyDesc = computed(
  () => `${lotId.value}/${wfNo.value}/${cpNo.value}/${rpNo.value}`
);

// const API_GetSiteTestInfo = "https://localhost:44389/api/Stdf/GetSiteTestInfo"; // 后端获取site信息
// const API_GetTestName = "https://localhost:44389/api/Stdf/GetTestName"; // 后端获取测试项名称
// const API_GetDbPath = "https://localhost:44389/api/Stdf/resolve"; // 后端获取数据库路径

const API_GetSiteTestInfo = "http://10.0.8.42:8089/api/Stdf/GetSiteTestInfo"; // 后端获取site信息
const API_GetTestName = "http://10.0.8.42:8089/api/Stdf/GetTestName"; // 后端获取测试项名称
const API_GetDbPath = "http://10.0.8.42:8089/api/Stdf/resolve"; // 后端获取数据库路径

async function load() {
  if (!current.value) {
    return;
  }

  try {
    const { data: testNameData } = await axios.get<any[]>(API_GetTestName, {
      params: {
        dbPath: current.value?.dbPath
      }
    });
    tests.value = testNameData.map(item => ({
      id: item.testId,
      label: item.testName
    }));
  } catch (error) {
    ElMessage.error("获取测试项名称失败:", error);
  } finally {
  }
}

async function onResolve() {
  if (!lotId.value || !wfNo.value || !cpNo.value || !rpNo.value) {
    ElMessage.warning("请完整填写 LOTID / WFNO / CP / RP");
    return;
  }
  loading.value = true;
  isDownloading.value = true;
  try {
    // 调用你后端的 Oracle 解析+缓存接口
    const { data } = await axios.get(API_GetDbPath, {
      params: {
        lotId: lotId.value,
        wfNo: wfNo.value,
        cpNo: cpNo.value,
        rpNo: rpNo.value
      }
    });
    const rec = {
      lotId: data.lotId,
      wfNo: data.wfNo,
      cpNo: data.cp,
      rpNo: data.rp,
      md5: data.stdfMD5,
      dbPath: data.dbPath,
      fromCache: !!data.fromCache,
      time: Date.now()
    };
    store.setCurrent(rec);
    console.log("注入缓存", rec);
    ElMessage.success(
      `OK:${rec.fromCache ? "命中缓存" : "已解析"},MD5=${rec.md5}`
    );
    if (rec.fromCache) {
      isDownloading.value = false;
    }
    await load();
    await loadTableData();
  } catch (err: any) {
    console.error(err);
    ElMessage.error(err?.response?.data?.detail || err.message || "解析失败");
  } finally {
    loading.value = false;
  }
}

async function loadLast() {
  const rec = store.getByKey({
    lotId: lotId.value,
    wfNo: wfNo.value,
    cpNo: cpNo.value,
    rpNo: rpNo.value
  });
  if (!rec) {
    ElMessage.info("该 Key 没有历史记录");
    return;
  }
  store.setCurrent(rec);
  ElMessage.success(`已加载历史 MD5=${rec.md5}`);
  await load();
  await loadTableData();
}

onMounted(() => {
  store.load();
});

// 要筛选哪个测试项
const search = ref("");
// 当前激活哪个tab
const activeTab = ref("info");

// 解析stdf文件
const isDownloading = ref(false);
const tabelLoading = ref(false);

let loadingInstance = null;

// 测试项数据
const tests = ref([]);
// 选中的测试项
const selectedTestName = ref("");

// 文件信息
const fileInfo = ref({
  name: "MX06B_1C_CP_A_DR_HOFU44-01_CP1_RP0_20250806102004.STD",
  path: "C:/Users/wangyuxiang/Desktop/stdf",
  size: "22.05 MB",
  yield: "99.65%",
  tested: 7474,
  passed: 7448
});

// 表格数据（示例）
const testStats = ref([]);

// 计算文件的 MD5 校验值
const calculateMD5 = file => {
  return new Promise(resolve => {
    const spark = new SparkMD5.ArrayBuffer();
    const fileReader = new FileReader();
    fileReader.onload = e => {
      spark.append(e.target.result);
      resolve(spark.end());
    };
    fileReader.readAsArrayBuffer(file);
  });
};

// 将文件分割成多个分块
const chunkFile = file => {
  const chunkSize = 5 * 1024 * 1024; // 每个分块 5MB
  const chunkCount = Math.ceil(file.size / chunkSize);
  const chunks = [];
  let currentChunkIndex = 0;

  while (currentChunkIndex < chunkCount) {
    const start = currentChunkIndex * chunkSize;
    const end = Math.min(start + chunkSize, file.size);
    chunks.push(file.slice(start, end));
    currentChunkIndex++;
  }

  return chunks;
};

// 获取已上传的分块信息
const getUploadedChunks = async md5 => {
  try {
    const response = await fetch(`${uploadStatus}?md5=${md5}`);
    const data = await response.json();
    return data.uploadedChunks || [];
  } catch (error) {
    ElMessage.error("Error fetching uploaded chunks", error);
    return [];
  }
};

// 处理文件选择前的逻辑
const beforeUpload = async file => {
  fileMD5.value = await calculateMD5(file); // 计算文件 MD5

  chunkedFile.value = chunkFile(file); // 将文件分割成块
  totalChunks.value = chunkedFile.value.length; // 获取文件总块数
  currentChunk.value = 0; // 当前分块索引初始化

  // 获取已上传的分块信息
  uploadedChunks.value = await getUploadedChunks(fileMD5.value);

  // 过滤掉已上传的分块，只上传剩余的分块
  chunkedFile.value = chunkedFile.value.filter(
    (_, index) => !uploadedChunks.value.includes(index)
  );

  // 如果没有剩余分块，说明文件已上传完毕
  if (chunkedFile.value.length === 0) {
    ElMessage.success("文件已完全上传");
    return false;
  }

  return true; // 继续上传文件
};

// 上传文件的分块
const uploadChunk = async index => {
  const formData = new FormData();
  formData.append("file", chunkedFile.value[index]);
  formData.append("index", index);
  formData.append("md5", fileMD5.value);
  formData.append("totalChunks", totalChunks.value);

  try {
    const response = await axios.post(uploadUrl, formData, {
      headers: {
        "Content-Type": "multipart/form-data"
      }
    });
    if (response.data.message == "数据不完整") {
      currentChunk.value = index + 1; // 更新当前上传的分块
    }
  } catch (error) {
    ElMessage.error("Error uploading chunk", error);
  }
};

// 上传所有剩余的分块
const uploadChunks = async () => {
  for (let i = 0; i < chunkedFile.value.length; i++) {
    await uploadChunk(i); // 上传每个分块
  }
};

// 自定义上传请求
const customRequest = async ({ file, onSuccess, onError }) => {
  isDownloading.value = true;
  loadingInstance = ElLoading.service({
    lock: true,
    text: "正在上传文件，请稍候...",
    background: "rgba(0,0,0,0.3)"
  });

  // 选择文件后，进行分块上传
  await uploadChunks();

  // 上传完成后
  if (loadingInstance) {
    loadingInstance.close();
  }
  onSuccess(); // 上传成功
};

// websocekt
const connection = new signalR.HubConnectionBuilder()
  .withUrl("http://10.0.8.42:8089/progressHub")
  .build();

connection.on("ReceiveProgress", progress => {
  uploadProgress.value = progress;

  if (uploadProgress.value == 100) {
    isDownloading.value = false;
  }
});

connection.start().then(() => {
  console.log("✅ SignalR 连接成功！");
});

// 上传失败的回调
const handleError = (err, file) => {
  ElMessage.error("文件上传失败error");
};

const filteredTests = computed(() => {
  if (!search.value) return tests.value;
  return tests.value.filter(t =>
    t.label.toLowerCase().includes(search.value.toLowerCase())
  );
});

const handleTestClick = async node => {
  selectedTestName.value = node.label;
  if (activeTab.value !== "info") {
    return;
  }
  await loadTableData();
};

const loadTableData = async () => {
  if (!selectedTestName.value) {
    ElMessage.info("请先选择测试项");
    return;
  }
  tabelLoading.value = true;

  const { data } = await axios.get<any[]>(API_GetSiteTestInfo, {
    params: {
      testName: selectedTestName.value,
      dbPath: current.value?.dbPath
    }
  });
  testStats.value = data;
  tabelLoading.value = false;
};

watch(
  () => activeTab.value,
  async newTab => {
    if (newTab === "info" && selectedTestName.value) {
      await loadTableData();
    }
  }
);
</script>

<style scoped>
.custom-dialog .el-dialog__header {
  background-color: #409eff; /* 标题栏背景色 */
  color: white; /* 标题字体颜色 */
  font-weight: bold;
  border-radius: 6px 6px 0 0; /* 圆角 */
}

.custom-dialog .el-dialog__body {
  padding: 20px;
  background-color: #f9f9f9;
  border-radius: 6px;
}

.dialog-content {
  text-align: center;
}

.dialog-text {
  font-size: 16px;
  color: #333;
  margin-bottom: 20px;
}

.progress-bar {
  margin-top: 20px;
}

.el-progress {
  height: 26px;
  border-radius: 13px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.el-progress__text {
  color: #333;
  font-weight: 500;
}

.el-progress__line {
  border-radius: 13px; /* 圆角效果 */
  background-color: #e4e7ed; /* 进度条底色 */
}

.el-progress__bar {
  border-radius: 13px; /* 圆角效果 */
  background-color: #409eff; /* 进度条颜色 */
}

.el-card {
  border-radius: 6px;
  margin-bottom: 12px;
}

.tree-node-text {
  display: inline-block;
  max-width: 100%; /* 或者你可以设置一个固定的宽度, 例如 200px */
  white-space: nowrap; /* 防止换行 */
  overflow: hidden; /* 隐藏超出的内容 */
  text-overflow: ellipsis; /* 显示省略号 */
}
</style>
